package com.acme.chat.newclient;

import java.util.HashSet;
import java.util.Set;

import com.acme.chat.message.MessageType;

public class Client {
    private enum Status {CONNECTED, DISCONNECTED};

    private String name;
    private String room;

    private Set<String> users;

    private Set<SendMessageListener> sendMessageListeners = new HashSet<SendMessageListener>();
    private Set<IncommingMessageListener> incommingMessageListeners = new HashSet<IncommingMessageListener>();

    private Status status = Status.DISCONNECTED;

    public Client(String name) {
        this.name = name;
        this.room = "Main";
        users = new HashSet<String>();
        users.add(name);
    }

    public void incommingMessage(ServerMessage message) {
        process(message);
        notifyIncommingMessageListeners(message);
    }

    private void process(ServerMessage message) {
        MessageType type = message.getType();

        switch (type) {
        case MESSAGE:
            break;
        case USERS_LIST:
            this.users = new HashSet<String>(message.getUsersList());
            break;
        case USER_CONNECTED:
            users.add(message.getConnectedName());
            break;
        case USER_DISCONNECTED:
            users.remove(message.getDisconnectedName());
            break;
        case CONNECTED:
            this.status = Status.CONNECTED;
            break;
        case DISCONNECTED:
            this.status = Status.DISCONNECTED;
            break;
        default:
            break;
        }
    }

    public void sendMessage(ClientMessage message) {
        notifySendMessageListeners(message);
    }

    public void disconnect() {
        sendMessage(new ClientMessage(MessageType.DISCONNECT));
        users = new HashSet<String>();
        status = Status.DISCONNECTED;
    }

    public void addIncommingMessageListener(IncommingMessageListener listener) {
        incommingMessageListeners.add(listener);
    }

    public void removeIncommingMessageListener(IncommingMessageListener listener) {
        incommingMessageListeners.remove(listener);
    }

    public void addSendMessageListener(SendMessageListener listener) {
        sendMessageListeners.add(listener);
    }

    public void removeSendMessageListener(SendMessageListener listener) {
        sendMessageListeners.remove(listener);
    }

    private void notifyIncommingMessageListeners(ServerMessage message) {
        for (IncommingMessageListener listener : incommingMessageListeners) {
            listener.onIncommingMessage(message);
        }
    }

    private void notifySendMessageListeners(ClientMessage message) {
        for (SendMessageListener listener : sendMessageListeners) {
            listener.onSendMessage(message);
        }
    }

    public String getRoom() {
        return room;
    }

    public void setRoom(String room) {
        this.room = room;
    }

    public String getName() {
        return name;
    }

    public Set<String> getUsers() {
        return users;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (!(o instanceof Client)) {
            return false;
        }
        return this.name.equals(((Client) o).name);
    }

    @Override
    public String toString() {
        return "Client: " + name;
    }


}
